package com.pk.platform.business.question.service.impl;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import com.pk.platform.business.question.dao.IPaperDefineDao;
import com.pk.platform.business.question.service.IPaperDefineService;
import com.pk.platform.business.question.vo.PaperVO;
import com.pk.platform.domain.privilege.User;
import com.pk.platform.domain.question.CodeTable;
import com.pk.platform.domain.question.ItemOption;
import com.pk.platform.domain.question.Paper;
import com.pk.platform.domain.question.Question;
import com.pk.platform.domain.question.QuestionKey;
import com.pk.platform.util.DateConverter;
import com.pk.platform.util.FileUtil;
import com.pk.platform.util.StringConverter;
import com.pk.platform.util.constant.Constant;
import com.pk.platform.util.constant.QuestionConstant;
import com.pk.platform.util.filter.SystemContext;
import com.pk.platform.util.page.Pager;

public class PaperDefineServiceImpl implements IPaperDefineService {
	
	private IPaperDefineDao paperDefineDao;
	
	public List<Map<String, Object>> queryPaperByPage(PaperVO pvo, Pager pager)
	{
		return paperDefineDao.queryPaperByPage(pvo, pager);
	}
	
	public List<Map<String, Object>> queryCodeTableByPaper(String paperId, String ctType)
	{
		return paperDefineDao.queryCodeTableByPaper(paperId, ctType);
	}
	
	public List<Map<String, Object>> queryItemOptionByCodeTable(String ctId)
	{
		return paperDefineDao.queryItemOptionByCodeTable(ctId);
	}
	
	public synchronized String addPaper(Paper paper)
	{
		boolean hasCode = paperDefineDao.exist("paper", "paperCode", paper.getPaperCode());
		if(hasCode == true)
		{
			return "[{'result':'hasCode'}]";
		}
		else
		{
			paperDefineDao.add(paper);
		}
		return "[{'result':'success', 'id':'" + paper.getId() + "'}]";
	}
	
	public void updatePaper(Paper paper)
	{
		Paper p = this.queryPaperById(paper.getId());
		p.setPaperName(paper.getPaperName());
		p.setPaperTime(paper.getPaperTime());
		p.setHalfQesRow(paper.getHalfQesRow());
		p.setFullQesRow(paper.getFullQesRow());
	}
	
	public String delPaper(String id)
	{
		Paper paper = this.queryPaperById(id);
		if(paper.getPaperFixSet().size() > 0)
		{
			return "error";
		}
		else
		{
			paperDefineDao.delete(Paper.class, id);
		}
		return "";
	}
	
	public Paper queryPaperById(String id)
	{
		return paperDefineDao.get(Paper.class, id);
	}
	
	public synchronized Map<String, Object> addCodeTable(CodeTable ct)
	{
		Map<String, Object> resultMap = new HashMap<String, Object>();
		String result = "result";
		boolean flag = paperDefineDao.existCodeTableCode(ct.getPaper().getId(), ct.getCode(), null);
		if(flag == true)
		{
			resultMap.put(result, "hasCode");
			return resultMap;
		}
		else
		{
			paperDefineDao.add(ct);
			paperDefineDao.getHibernateSession().flush();
			List<Map<String, Object>> ctList = this.queryCodeTableByPaper(ct.getPaper().getId(), ct.getCtType());
			resultMap.put(result, "");
			resultMap.put("id", ct.getId());
			resultMap.put("ctType", ct.getCtType());
			resultMap.put("ctList", ctList);
		}
		return resultMap;
	}
	
	public Map<String, Object> updateCodeTable(CodeTable ct)
	{
		Map<String, Object> resultMap = new HashMap<String, Object>();
		String result = "result";
		CodeTable codeTable = this.queryCodeTableById(ct.getId());
		boolean flag = paperDefineDao.existCodeTableCode(codeTable.getPaper().getId(), ct.getCode(), codeTable.getId());
		if(flag == true)
		{
			resultMap.put(result, "hasCode");
			return resultMap;
		}
		else
		{
			if((Constant.N.equals(ct.getHasHalfQes()) || ct.getHasHalfQes() == null) && Constant.Y.equals(codeTable.getHasHalfQes()))
			{
				Set<Question> qesSet = codeTable.getQesOfCodeTableSet();
				for(Question qes : qesSet)
				{
					paperDefineDao.delQuestionKeyByHalfOpen(qes.getId());
				}
			}
			codeTable.setCode(ct.getCode());
			codeTable.setDescription(ct.getDescription());
			codeTable.setHasHalfQes(ct.getHasHalfQes());
			codeTable.setHalfQesVal(ct.getHalfQesVal());
			codeTable.setHalfQesWidth(ct.getHalfQesWidth());
			codeTable.setHalfQesQuantity(ct.getHalfQesQuantity());
			paperDefineDao.getHibernateSession().flush();
			List<Map<String, Object>> ctList = this.queryCodeTableByPaper(codeTable.getPaper().getId(), ct.getCtType());
			resultMap.put(result, "");
			resultMap.put("ctType", ct.getCtType());
			resultMap.put("ctList", ctList);
		}
		return resultMap;
	}
	
	public Map<String, Object> delCodeTable(String id)
	{
		CodeTable ct = this.queryCodeTableById(id);
		Set<Question> qesOfCodeTableSet = ct.getQesOfCodeTableSet();
		Set<Question> qesOfGroupQesSet = ct.getQesOfGroupQesSet();
		for(Question qes : qesOfCodeTableSet) //删除码表关系
		{
			qes.setCodeTable(null);
		}
		for(Question qes : qesOfGroupQesSet) //删除组题关系
		{
			qes.setCodeTable(null);
		}
		Map<String, Object> resultMap = new HashMap<String, Object>();
		paperDefineDao.delete(CodeTable.class, id);
		paperDefineDao.getHibernateSession().flush();
		List<Map<String, Object>> ctList = this.queryCodeTableByPaper(ct.getPaper().getId(), ct.getCtType());
		resultMap.put("ctList", ctList);
		return resultMap;
	}
	
	public CodeTable queryCodeTableById(String id)
	{
		return paperDefineDao.get(CodeTable.class, id);
	}
	
	public String addItemOption(String keyArray, String labelArray, String ctId)
	{
		String sp = "#split#";
		String[] keys = keyArray.split(sp);
		String[] labels = labelArray.split(sp);
		int len = keys.length;
		for(int i = 0; i < len; i++)
		{
			ItemOption io = new ItemOption();
			io.setOptionValue(keys[i]);
			io.setDescription(labels[i]);
			CodeTable ct = new CodeTable();
			ct.setId(ctId);
			io.setCodeTable(ct);
			paperDefineDao.add(io);
		}
		return null;
	}
	
	public String delItemOption(String[] id)
	{
		for(String newId : id)
		{
			ItemOption io = this.queryItemOptionById(newId);
			CodeTable codeTable = io.getCodeTable();
			Set<Question> qesSet = codeTable.getQesOfCodeTableSet();
			for(Question qes : qesSet)
			{
				//删除所有问题答案的该选项
				paperDefineDao.delQuestionKeyByItemOption(qes.getId(), io.getOptionValue());
				
				//如果是删除开放题
				if(Constant.Y.equals(codeTable.getHasHalfQes()) && io.getOptionValue().equals(codeTable.getHalfQesVal()))
				{
					paperDefineDao.delQuestionKeyByHalfOpen(qes.getId());
				}
			}
			paperDefineDao.delete(ItemOption.class, newId);
		}
		return null;
	}
	
	public void updateItemOption(ItemOption io)
	{
		ItemOption option = this.queryItemOptionById(io.getId());
		option.setFocusEvent(io.getFocusEvent());
		option.setKeyEvent(io.getKeyEvent());
	}
	
	public ItemOption queryItemOptionById(String id)
	{
		return paperDefineDao.get(ItemOption.class, id);
	}
	
	public List<Map<String, Object>> queryQuestionByPage(PaperVO pvo, Pager pager)
	{
		return paperDefineDao.queryQuestionByPage(pvo, pager);
	}
	
	public Map<String, Object> addQuestion(Question question)
	{
		Map<String, Object> resultMap = new HashMap<String, Object>();
		String result = "result";
		boolean flag = paperDefineDao.existQuestionCode(question.getPaper().getId(), question.getQesCode(), null);
		if(flag)
		{
			resultMap.put(result, "hasCode");
			return resultMap;
		}
		else
		{
			if(question.getCodeTable() != null && !StringConverter.isNotNull(question.getCodeTable().getId()))
			{
				question.setCodeTable(null);
			}
			if(question.getGroupQes() != null && !StringConverter.isNotNull(question.getGroupQes().getId()))
			{
				question.setGroupQes(null);
			}
			question.setPage(1);
			paperDefineDao.add(question);
			resultMap.put(result, "");
			resultMap.put("id", question.getId());
		}
		return resultMap;
	}
	
	public String updateQuestion(Question question)
	{
		Question qes = this.queryQuestionById(question.getId());
		boolean flag = paperDefineDao.existQuestionCode(qes.getPaper().getId(), question.getQesCode(), qes.getId());
		if(flag == true)
		{
			return "hasCode";
		}
		else
		{
			Set<QuestionKey> qkSet = qes.getQuestionKeySet();
			for(QuestionKey qk : qkSet)
			{
				String txtId = qk.getTxtId();
				String newTxtId = txtId.replace(QuestionConstant.TXT_CODE + qes.getQesCode(), QuestionConstant.TXT_CODE + question.getQesCode());
				qk.setTxtId(newTxtId);
			}
			paperDefineDao.getHibernateSession().flush();
			qes.setQesCode(question.getQesCode());
			qes.setQesType(question.getQesType());
			qes.setQesTitle(question.getQesTitle());
			qes.setFocusEvent(question.getFocusEvent());
			qes.setKeyEvent(question.getKeyEvent());
			qes.setWidth(question.getWidth());
			qes.setQuantity(question.getQuantity());
			qes.setCodeTable(question.getCodeTable());
			qes.setGroupQes(question.getGroupQes());
		}
		return "";
	}
	
	public Question queryQuestionById(String id)
	{
		return paperDefineDao.get(Question.class, id);
	}

	public Question queryQuestionByCode(String code)
	{
		return paperDefineDao.get(Question.class, code);
	}
	
	public void delQuestion(String id)
	{
		paperDefineDao.delete(Question.class, id);
	}

	public IPaperDefineDao getPaperDefineDao() {
		return paperDefineDao;
	}

	public void setPaperDefineDao(IPaperDefineDao paperDefineDao) {
		this.paperDefineDao = paperDefineDao;
	}
	
	public Map<String, String> exportPaperMap(String paperId, HttpServletRequest request)
	{
		User user = SystemContext.getUser();
		String realPath = request.getSession().getServletContext().getRealPath("/jsp/login/fileUpload/tempForDownload/");
		String fileName = user.getId() + "_mapping.csv";
		String fullPath = realPath + "/" + fileName;
		File file = new File(fullPath);
		try
		{
			FileUtil.makeFile(file);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
		this.exportMapCsv(paperId, fullPath); //写文件
		Map<String, String> map = new HashMap<String, String>();
		map.put("filePath", fullPath);
		map.put("name", fileName);
		return map;
	}
	
	private void exportMapCsv(String paperId, String fullPath)
	{
		Paper paper = this.queryPaperById(paperId);
		String sign = Constant.CSV_SIGN;
		FileUtil fu = new FileUtil(fullPath);
		fu.clean();
		StringBuffer title = new StringBuffer();
		title.append(paper.getPaperName()).append(sign).append(DateConverter.dateToString(paper.getPaperTime(), DateConverter.FORMAT_ONE));
		fu.appendLine(title.toString());
		fu.appendLine("");
		StringBuffer head = new StringBuffer();
		head.append("No.,Name,Question,Caption,Label,StartColumn,FieldWidth,FieldCount,Column Spec.,CodeType,HalfOpenCode");
		fu.appendLine(head.toString());
		Set<Question> qesSet = paper.getQuestionSet();
		int i = 1;
		int startColumn = 1;
		String fixed = "Fixed";
		String open = "Open";
		String coding = "Coding";
		String num = "Num";
		for(Question qes : qesSet)
		{
			StringBuffer line = new StringBuffer();
			line.append(i).append(sign);
			if(QuestionConstant.SINGLE_CHOICE.equals(qes.getQesType().getId()))
			{
				CodeTable ct = qes.getCodeTable();
				line.append(qes.getQesCode()).append(sign).append(qes.getQesCode());
				line.append(sign).append(qes.getQesTitle()).append(sign).append(qes.getQesTitle());
				line.append(sign).append(startColumn).append(sign).append(qes.getWidth());
				line.append(sign).append(1).append(sign);
				if(qes.getWidth() == 1)
				{
					line.append("\"c").append(startColumn).append("\"");
				}
				else
				{
					line.append("\"c(").append(startColumn).append(",").append(startColumn + qes.getWidth() - 1).append(")\"");
				}
				line.append(sign).append(fixed);
				if(Constant.Y.equals(ct.getHasHalfQes()))
				{
					line.append(" & ").append(open);
					line.append(sign).append(ct.getHalfQesVal());
					//把halfQes的信息添加到array
				}
				startColumn += qes.getWidth();
				i++;
			}
			else if(QuestionConstant.NUMERIC_VALUE.equals(qes.getQesType().getId()))
			{
				
			}
			else if(QuestionConstant.MULTIPLE_CHOICE.equals(qes.getQesType().getId()))
			{
				
			}
			else if(QuestionConstant.FULL_OPEN.equals(qes.getQesType().getId()))
			{
				
			}
			else if(QuestionConstant.GROUP_SINGLE.equals(qes.getQesType().getId()))
			{
				
			}
			else if(QuestionConstant.GROUP_NUMERIC.equals(qes.getQesType().getId()))
			{
				
			}
			else if(QuestionConstant.GROUP_MULTIPLE.equals(qes.getQesType().getId()))
			{
				
			}
			
			fu.appendLine(line.toString());
		}
	}
	
	
	
	

}
